package com.awesumgames.awesum;

import static java.lang.Math.sqrt;

import java.util.Locale;

public final class Vector4 {

	public float x, y, z, a;
	
	public Vector4() {
		x = y = z = a = 0f;
	}
	public Vector4(Vector4 v2) {
		x = v2.x;
		y = v2.y;
		z = v2.z;
		a = v2.a;
	}
	public Vector4(float x, float y, float z, float a) {
		this.x = x; this.y = y; this.z = z; this.a = a;
	}
	public Vector4(double x, double y, double z) {
		this.x = (float)x; this.y = (float)y; this.z = (float)z; this.a = (float)a;
	}
	
	public String toString() {
		return String.format(Locale.US, "(%f, %f, %f, %f)", x, y, z, a);
	}
	
	public Vector4 copy() {
		return new Vector4(this);
	}
	
	public boolean equals(Vector4 v2) {
		return x == v2.x && y == v2.y && z == v2.z && a == v2.a;
	}
	public boolean equals(float nx, float ny, float nz, float na) {
		return x == nx && y == ny && z == nz && a == na;
	}

	public Vector4 set(Vector4 v2) {
		this.x = v2.x; this.y = v2.y; this.z = v2.z; this.a = v2.a;
		return this;
	}
	public Vector4 set(float x, float y, float z, float a) {
		this.x = x; this.y = y; this.z = z; this.a = a;
		return this;
	}

	public Vector4 add(Vector4 v2) {
		x += v2.x; y += v2.y; z += v2.z; a += v2.a;
		return this;
	}
	public Vector4 add(float s) {
		x += s; y += s; z += s; a += s;
		return this;
	}
	public Vector4 add(float ax, float ay, float az, float aa) {
		x += ax; y += ay; z += az; a += aa;
		return this;
	}
	public Vector4 subtract(Vector4 v2) {
		x -= v2.x; y -= v2.y; z -= v2.z; a -= v2.a;
		return this;
	}
	public Vector4 multiply(float s) { //Scalar multiply
		x *= s; y *= s; z *= s; a *= s;
		return this;
	}
	public Vector4 multiply(Vector4 v2) { //Scalar multiply individual components
		x *= v2.x; y *= v2.y; z *= v2.z; a *= v2.a;
		return this;
	}
	public Vector4 divide(float s) { //Scalar divide
		x /= s; y /= s; z /= s; a /= s;
		return this;
	}
	public Vector4 divide(Vector4 v2) { //Scalar divide individual components
		x /= v2.x; y /= v2.y; z /= v2.z; a /= v2.a;
		return this;
	}
	public Vector4 mod(float s) { //Scalar modulo
		x %= s; y %= s; z %= s; a %= s;
		return this;
	}
	public Vector4 negate() {
		x=-x;y=-y;z=-z;a=-a; //2x fast as multiply(-1)
		return this;
	}
	public float magnitude() {
		return (float)sqrt(magnitudeSq());
	}
	public float magnitudeSq() {
		return x*x + y*y + z*z + a*a;
	}
	
	public Vector4 abs() {
		x = Math.abs(x);
		y = Math.abs(y);
		z = Math.abs(z);
		a = Math.abs(a);
		return this;
	}
	
	public void normalize() {
		divide(magnitude());
	}
	public Vector4 normal() {
		float m = magnitude();
		return new Vector4(x / m, y / m, z / m, a / m);
	}
	public float dot(Vector4 v2) {
		return x*v2.x + y*v2.y + z*v2.z + a*v2.a;
	}
	public Vector4 cross(Vector4 v2, Vector4 v3) {//yz-zy, zx-xz, xy-yx
		return new Vector4(	y*(v2.z*v3.a - v3.z*v2.a) - z*(v2.y*v3.a - v3.y*v2.a) + a*(v2.y*v3.z - v3.y*v2.z),
							-x*(v2.z*v3.a - v3.z*v2.a) + z*(v2.x*v3.a - v3.x*v2.a) - a*(v2.x*v3.z - v3.x*v2.z),
							x*(v2.y*v3.a - v3.y*v2.a) - y*(v2.x*v3.a - v3.x*v2.a) + a*(v2.x*v3.y - v3.x*v2.y),
							-x*(v2.y*v3.z - v3.y*v2.z) + y*(v2.x*v3.z - v3.x*v2.z) - z*(v2.x*v3.y - v3.x*v2.y));
	}
	public float distFrom(Vector4 v2) {
		return (float)sqrt(distSqFrom(v2));
	}
	public float distSqFrom(Vector4 v2) {
		float dx = x-v2.x, dy = y-v2.y, dz = z-v2.z, da = a-v2.a;
		return dx*dx + dy*dy + dz*dz + da*da;
	}
}
